﻿#include "PhaseIdentify.h"
#include "public.h"
#include "mainwindow.h"
#include "easylogging++.h"

PhaseIdentify::PhaseIdentify(MainWindow& mw, std::shared_ptr<SerialPort> sp) : mainWindow(mw), serialPort(sp) {
	this->queryNodeNumber = constructMsgData({ 0x05, 0x03, 0x00, 0xe8 }, 0x03, {});
	this->batchQueryNodePhaseInfo = constructMsgData({ 0x0d, 0x03, 0x03, 0xe8 }, 0x03, {});
}

void PhaseIdentify::sendQueryNodeNumber() {
	auto msg_data = this->queryNodeNumber;
	QByteArray msg = vectorToByteArray(msg_data);
	if (!this->serialPort->cacheWaitConfirmMsg(SerialPort::queryNodeNumberReq, msg)) {
		LOG(ERROR) << "Message has not been confirmed, cmd:" << convertToString(SerialPort::queryNodeNumberReq).toStdString() << ", msg:" << convertToString(msg).toStdString();
		return;
	}
	this->serialPort->sendMsg(msg);
}

void PhaseIdentify::sendBatchQueryNodePhaseInfo() {
	auto msg_data = this->batchQueryNodePhaseInfo;
	QByteArray msg = vectorToByteArray(msg_data);
	if (!this->serialPort->cacheWaitConfirmMsg(SerialPort::batchQueryNodePhaseInfoReq, msg)) {
		LOG(ERROR) << "Message has not been confirmed, cmd:" << convertToString(SerialPort::batchQueryNodePhaseInfoReq).toStdString() << ", msg:" << convertToString(msg).toStdString();
		return;
	}
	this->serialPort->sendMsg(msg);
}

void PhaseIdentify::handleQueryNodeNumberResult(const QByteArray relayMessage) {
	this->nodeTotalCnt = uint8_t(relayMessage[11]) << 8 | uint8_t(relayMessage[10]);// 总数量
	LOG(INFO) << "nodeTotalCnt:" << this->nodeTotalCnt << ", hasSearchedPhaseInfoNodeCnt:" << hasSearchedPhaseInfoNodeCnt;
	if (nodeTotalCnt - hasSearchedPhaseInfoNodeCnt > 0) {
		LOG(INFO) << "(int)(hasSearchedPhaseInfoNodeCnt & 0xFF):" << (int)(hasSearchedPhaseInfoNodeCnt & 0xFF) << ", (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF):" << (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF);
		std::vector<int> content = { (int)(hasSearchedPhaseInfoNodeCnt & 0xFF), (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF), 0x10 };
		this->batchQueryNodePhaseInfo = constructMsgData({ 0x0d, 0x03, 0x03, 0xe8 }, 0x03, content);
		// 发送批量查询从节点相位信息
		sendBatchQueryNodePhaseInfo();
	}
}

void PhaseIdentify::handleBatchQueryNodePhaseInfoResult(const QByteArray& relayMessage) {
	uint32_t currentCnt = relayMessage[12];
	hasSearchedPhaseInfoNodeCnt += currentCnt;
	for (int index = 0; index < currentCnt; ++index) {
		std::vector<int> nodeAddr;
		nodeAddr.push_back(relayMessage[13 + index * 8 + 5]);
		nodeAddr.push_back(relayMessage[13 + index * 8 + 4]);
		nodeAddr.push_back(relayMessage[13 + index * 8 + 3]);
		nodeAddr.push_back(relayMessage[13 + index * 8 + 2]);
		nodeAddr.push_back(relayMessage[13 + index * 8 + 1]);
		nodeAddr.push_back(relayMessage[13 + index * 8 + 0]);
		auto nodeAddrStr = convertToStringToShow(vectorToByteArray(nodeAddr));

		auto phaseInfoIt = allNodePhaseInfo.find(nodeAddrStr);
		uint8_t phaseInfo = relayMessage[13 + index * 8 + 6];
		if (phaseInfoIt != allNodePhaseInfo.end()) {
			// 相位信息没有变化，无需更新
			if (phaseInfo == phaseInfoIt->second) {
				continue;
			}
			else {
				// 先减少数量
				eraseOldCnt(phaseInfoIt->second);
				// 更新缓存相位信息
				phaseInfoIt->second = phaseInfo;
			}
		}
		else {
			allNodePhaseInfo[nodeAddrStr] = phaseInfo;
		}

		QString phaseSequenceType = "未知";
		QString physicalPhase = "未知";
		decodePhaseInfo(phaseInfo, phaseSequenceType, physicalPhase);
		mainWindow.updatePhaseViewModel(nodeAddrStr, phaseSequenceType, physicalPhase, phaseCnt);
	}
	LOG(INFO) << "nodeTotalCnt:" << this->nodeTotalCnt << ", hasSearchedPhaseInfoNodeCnt:" << hasSearchedPhaseInfoNodeCnt;
	if (nodeTotalCnt - hasSearchedPhaseInfoNodeCnt > 0) {
		LOG(INFO) << "(int)(hasSearchedPhaseInfoNodeCnt & 0xFF):" << (int)(hasSearchedPhaseInfoNodeCnt & 0xFF) << ", (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF):" << (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF);
		std::vector<int> content = { (int)(hasSearchedPhaseInfoNodeCnt & 0xFF), (int)((hasSearchedPhaseInfoNodeCnt >> 16) & 0xFF), 0x10 };
		this->batchQueryNodePhaseInfo = constructMsgData({ 0x0d, 0x03, 0x03, 0xe8 }, 0x03, content);
		// 发送批量查询从节点相位信息
		sendBatchQueryNodePhaseInfo();
	}
	else {
		hasSearchedPhaseInfoNodeCnt = 0;
	}
}

void PhaseIdentify::decodePhaseInfo(uint8_t phaseInfo, QString& phaseSequenceType, QString& physicalPhase) {
	phaseSequenceType = "未知";
	physicalPhase = "未知";
	if ((phaseInfo & phaseTypeMask) == phaseTypeNormalA) {
		phaseSequenceType = "正常";
		physicalPhase = "A相";
		phaseCnt[0]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalB) {
		phaseSequenceType = "正常";
		physicalPhase = "B相";
		phaseCnt[1]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalC) {
		phaseSequenceType = "正常";
		physicalPhase = "C相";
		phaseCnt[2]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseA) {
		phaseSequenceType = "零火反接";
		physicalPhase = "A相";
		phaseCnt[0]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseB) {
		phaseSequenceType = "零火反接";
		physicalPhase = "B相";
		phaseCnt[1]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseC) {
		phaseSequenceType = "零火反接";
		physicalPhase = "C相";
		phaseCnt[2]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalABC) {
		phaseSequenceType = "正常";
		physicalPhase = "A/B/C相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseABC) {
		phaseSequenceType = "零火反接";
		physicalPhase = "A/B/C相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseACB) {
		phaseSequenceType = "逆相序";
		physicalPhase = "A/C/B相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseBAC) {
		phaseSequenceType = "逆相序";
		physicalPhase = "B/A/C相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseBCA) {
		phaseSequenceType = "逆相序";
		physicalPhase = "B/C/A相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseCAB) {
		phaseSequenceType = "逆相序";
		physicalPhase = "C/A/B相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseCBA) {
		phaseSequenceType = "逆相序";
		physicalPhase = "C/B/A相";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackBC) {
		phaseSequenceType = "缺B/C相";
		physicalPhase = "A相/未知/未知";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackAC) {
		phaseSequenceType = "缺A/C相";
		physicalPhase = "B相/未知/未知";
		phaseCnt[3]++;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackAB) {
		phaseSequenceType = "缺A/B相";
		physicalPhase = "C相/未知/未知";
		phaseCnt[3]++;
	}
	else {
		phaseCnt[4]++;
	}
}

void PhaseIdentify::eraseOldCnt(uint8_t phaseInfo) {
	if ((phaseInfo & phaseTypeMask) == phaseTypeNormalA) {
		phaseCnt[0]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalB) {
		phaseCnt[1]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalC) {
		phaseCnt[2]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseA) {
		phaseCnt[0]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseB) {
		phaseCnt[1]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseC) {
		phaseCnt[2]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeNormalABC) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeReverseABC) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseACB) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseBAC) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseBCA) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseCAB) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeInverseCBA) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackBC) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackAC) {
		phaseCnt[3]--;
	}
	else if ((phaseInfo & phaseTypeMask) == phaseTypeLackAB) {
		phaseCnt[3]--;
	}
	else {
		phaseCnt[4]--;
	}
}